<script lang="ts" setup>
interface Props {
  src: string
  width: number | string
  height: number | string
  mode?: string
  rounded?: number | string
  showMenuByLongpress?: boolean
}

withDefaults(defineProps<Props>(), {
  mode: 'aspectFill',
  showMenuByLongpress: false,
})

const emit = defineEmits<{
  (e: 'click'): void
}>()

const loading = ref(true)
const error = ref(false)
const isUpdate = ref(false)
let count = 1
const load = () => {
  setTimeout(() => {
    loading.value = false
    error.value = false
  }, 300)
}
const errorImg = () => {
  setTimeout(() => {
    loading.value = false
    error.value = true
  }, 300)
}

const reload = () => {
  if (count > 4)
    return
  if (count > 3)
    return errorImg()
  isUpdate.value = true
  setTimeout(() => isUpdate.value = false)
  count++
}
</script>

<template>
  <view
    class="flex fast-lazy-load" :style="{
      'width': !isNaN(width as number) ? `${width}rpx` : width,
      'height': !isNaN(height as number) ? `${height}rpx` : height,
      'border-radius': !isNaN(rounded as number) ? `${rounded}rpx` : rounded,
      'background-color': !loading && !error ? 'transparent' : '#d9d9d9',
    }" @click="$emit('click')"
  >
    <view v-if="loading" class="loading flex-shrink-0">
      <slot name="loading">
        <!-- <image class="lazy-image" :src="getLaiImgPath('img_default.png')" mode="aspectFit" /> -->
        <image
          class="lazy-image" mode="aspectFit"
          src=""
        />
      </slot>
    </view>
    <view v-if="error" class="loading error flex-shrink-0">
      <slot name="error">
        <!-- <image class="lazy-image" :src="getLaiImgPath('img_default.png')" mode="aspectFit" /> -->
        <image
          class="lazy-image" mode="aspectFit"
          src=""
        />
      </slot>
    </view>
    <image
      v-if="!isUpdate" class="image" :show-menu-by-longpress="showMenuByLongpress"
      :src="`${src}?imageView2/0/format/webp/q/75`" :mode="mode" :class="{ show: !loading && !error }" :style="{
        'width': !isNaN(width as number) ? `${width}rpx` : width,
        'height': !isNaN(height as number) ? `${height}rpx` : height,
        'border-radius': !isNaN(rounded as number) ? `${rounded}rpx` : rounded,
      }" @load="load" @error="reload"
    />
  </view>
</template>

<style scoped lang="scss">
.fast-lazy-load {
  background: #e8e7e7;
  overflow: hidden;

  .loading {
    width: 100%;
    height: 100%;
    display: inline-flex;
    justify-content: center;
    align-items: center;

    .lazy-image {
      max-width: 310rpx;
      max-height: 196rpx;
      width: 50%;
      height: 50%;
    }
  }

  .image {
    transition: 0.3s opacity;
    opacity: 0;

    &.show {
      opacity: 1;
    }
  }
}
</style>
